/*
 * PBBconfig.java
 *
 * Created on June 7, 2007, 12:54 PM
 *
 *A class to parse the config file and hold all the config file data.
 *
 *Copyright 2007-2008 Jon W Huss III

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 *
 */
package pbb_template_updater;

import java.io.*;
import java.util.Vector;

/**
 *
 * @author Jon Huss
 */
public class PbbConfig {

    File configuration;
    LineNumberReader lnr;
//    String simpleIn = "";  //Depricated
    String simpleAlias = "";
//    String simpleOut = ""; //Depricated
    String xmlIn = "";
    String dataOut = "";
    String xmlSeek = "";
    String goTerms = "";
    String wikiDomain = "";
    String wikiUsername = "";
    String wikiPassword = "";
    String wikiFile = "";
    String botLog = "";
    String pageDir = "";
    String wikiMainLog = "";
    String wikiLogRun = "";
    //String expressionImages = "";
    String pageBase = "";
    //PBBLogging log;

    public String getPageBase() {
        return pageBase;
    }

    /** Simplified version of PbbConfig.  We don't use any logging, so we can initialize the class
     * and pull in all the values at the same time.  
     * 
     * Not that all output is sent to STD OUT and ERR.  It is assumed that for a log
     * those streams will be redirected to a file. 
     * 
     */
    public PbbConfig(String location) throws IOException {

        //Bind the logging module.

        configuration = new File(location);

//        if (configuration.canRead()) {
//            lnr = new LineNumberReader(new FileReader(configuration));
//
//        } else {
//            throw new IOException("Cannot Read Configuration File: " + location);
//        }
//        //First things first. we need to setup the logging. THis will have to be read
//        //from the configuration file..
//        if (log == null) {
//            String[] lineVals;
//            String line = "";
//            while ((line = this.getNextLine()) != null) {
//                line = line.trim();
//                //now check for a comment line..
//                if (line.matches("\\s*#.*")) {
//                    //got a comment, skip the rest
//                    line = this.getNextLine();
//                    continue;
//
//                }
//                //System.out.println(line);  //XXX DEBUG
//                lineVals = line.split("="); //switched to an equals deliminater
//
//                if (lineVals.length > 1) {
//                    if (lineVals[0].trim().toUpperCase().compareTo("BOT_LOG") == 0) {
//                        if (lineVals[1].compareTo("") != 0) {
//                            botLog = lineVals[1].trim();
//                        } else {
//                            throw new IOException("Parse Error: BotLog is blank.");
//                        }
//                    } else {
//                        //do nothing
//                    }
//                }
//            }
//            if (this.getBotLog().compareTo("") == 0) {
//                throw new Exception("Bot log cannot be blank, please check the configuration file and set BOT_LOG=<directory>");
//            } else {
//                log = new PBBLogging(this.getBotLog());
//            }
//            lnr.close();
//        }

        //now we are going to set the configuration file
        //then we will try and read all the configuration data from it.
        if (configuration.canRead()) {
            lnr = new LineNumberReader(new FileReader(configuration));

        } else {
            throw new IOException("Cannot Read Configuration File: " + location);
        }

        String[] lineVals;
        String line = "";
        //log.addEntry("System", "System", "Parsed Configuration:", PBBLogging.logs.SY);
        System.out.println("Parsing Configuration File...");
        line = this.getNextLine();
        //log.addSysHTML("<UL>");
        //log.addEntry("System","","<UL>",PBBLogging.logs.SY);
        while (line != null) {
            line = line.trim();
            //System.out.println(line);  //XXX DEBUG
            if (line.matches("\\s*#.*")) {
                //got a comment, skip the rest
                line = this.getNextLine();
                continue;

            }
            lineVals = line.split("="); //switched to a comma deliminater
            //if (lineVals.length > 0) {
            //    if ("#".compareTo(lineVals[0]) == 0) {
            //        //got a comment, skip the rest
            //        line = this.getNextLine();
            //        continue;
            //    }
            //}


            if (lineVals.length > 1) {
                //need to make sure there are at least two arguments in a line
                //Start the case switching.
//                if (lineVals[0].trim().toUpperCase().compareTo("SIMPLE_IN") == 0) {
//                    if (lineVals[1].compareTo("") != 0){
//                        simpleIn = lineVals[1].trim();
//                        log.addEntry("System","Simple Input",simpleIn,PBBLogging.logs.SY);
//                        System.out.println("Simple Input: " + simpleIn);
//                    } else {
//                        throw new IOException("Parse Error: Simple in is blank.");
//                    }
//                }else 
                if (lineVals[0].trim().toUpperCase().compareTo("SIMPLE_ALIAS") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        simpleAlias = lineVals[1].trim();
                        //log.addEntry("System", "Simple Alias", simpleAlias, PBBLogging.logs.SY);
                        System.out.println("Simple Alias: " + simpleAlias);
                    } else {
                        throw new IOException("Parse Error: Simple Alias is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("BOT_LOG") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        botLog = lineVals[1].trim();
                    } else {
                        throw new IOException("Parse Error: BotLog is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("DEBUG_PAGE_BASE") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        pageBase = lineVals[1].trim();
                        //log.addEntry("System", "Page Base", pageBase, PBBLogging.logs.SY);
                        System.out.println("DEBUG Page Base: " + pageBase);
                    } else {
                        pageBase = "";
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_MAIN_LOG") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiMainLog = lineVals[1].trim();
                        //log.addEntry("System", "Wiki Main Log Page: ", wikiMainLog, PBBLogging.logs.SY);
                        System.out.println("Main Wiki Log: " + wikiMainLog);
                    } else {
                        throw new IOException("Parse Error: Simple Out is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("DATA_OUT") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        dataOut = lineVals[1].trim();
                        //log.addEntry("System", "Data Output Directory: ", dataOut, PBBLogging.logs.SY);
                        System.out.println("Data Output Directory: " + dataOut);
                    } else {
                        throw new IOException("Parse Error: data_out is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_RUN_LOG") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiLogRun = lineVals[1].trim();
                        //log.addEntry("System", "Wiki Individual Run Log Page: ", wikiLogRun, PBBLogging.logs.SY);
                        System.out.println("Wiki Run Log: " + wikiLogRun);
                    } else {
                        throw new IOException("Parse Error: Simple Out is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("XML_IN") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        xmlIn = lineVals[1].trim();
                        //log.addEntry("System", "XML Input", xmlIn, PBBLogging.logs.SY);
                        System.out.println("XML Input: " + xmlIn);
                    } else {
                        throw new IOException("Parse Error: XML in is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("XML_SEEK") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        xmlSeek = lineVals[1].trim();
                        //log.addEntry("System", "XML Targets", xmlSeek, PBBLogging.logs.SY);
                        System.out.println("XML Seek File: " + xmlSeek);
                    } else {
                        throw new IOException("Parse Error: XML Seek is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("GO_TERMS") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        goTerms = lineVals[1].trim();
                        //log.addEntry("System", "Go Terms", goTerms, PBBLogging.logs.SY);
                        System.out.println("Go Terms File: " + goTerms);
                    } else {
                        throw new IOException("Parse Error: Go Terms is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_DOMAIN") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiDomain = lineVals[1].trim();
                        //log.addEntry("System", "Wikipedia URL", wikiDomain, PBBLogging.logs.SY);
                        System.out.println("Wikipedia URL: " + wikiDomain);
                    } else {
                        throw new IOException("Parse Error: wikiDomain is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_USERNAME") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiUsername = lineVals[1].trim();
                        //log.addEntry("System", "Wikipedia Username", wikiUsername, PBBLogging.logs.SY);
                        System.out.println("Wikipedia Username: " + wikiUsername);
                    } else {
                        throw new IOException("Parse Error: Wiki Username is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_PASSWORD") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiPassword = lineVals[1].trim();
                        //log.addEntry("System", "Wikipedia", "Password Aquired", PBBLogging.logs.SY);
                        System.out.println("Wikipedia password aquired.");
                    } else {
                        throw new IOException("Parse Error: wikiPassword is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("WIKI_FILE") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        wikiFile = lineVals[1].trim();
                        //log.addEntry("System", "Wikipedia Query File", wikiFile, PBBLogging.logs.SY);
                        System.out.println("Wikipedia query File name: " + wikiFile);
                    } else {
                        throw new IOException("Parse Error: wikiFile is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("BOT_LOG") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        botLog = lineVals[1].trim();
                        //log.addEntry("System", "Bot Logging Directory", botLog, PBBLogging.logs.SY);
                        System.out.println("Bot Logging Directory: " + botLog);
                    } else {
                        throw new IOException("Parse Error: BotLog is blank.");
                    }
                } else if (lineVals[0].trim().toUpperCase().compareTo("PAGE_DIR") == 0) {
                    if (lineVals[1].compareTo("") != 0) {
                        pageDir = lineVals[1].trim();
                        //log.addEntry("System", "Protein Page Directory", pageDir, PBBLogging.logs.SY);
                        System.out.println("Protein Page Directory: " + pageDir);
                    } else {
                        throw new IOException("Parse Error: Page Directory is Blank");
                    }
                } else {

                    //log.addEntry("System", "Warning", "Unknown Line in Configuration file. Ignored.", PBBLogging.logs.SY);
                    System.out.println("Warning: unknown line in configuration file: " + line);
                }
            }

            line = this.getNextLine();
        }//end while

        //log.addSysHTML("</UL><BR>");
        //log.addEntry("System","","</UL>",PBBLogging.logs.SY);
        //Should have all the locations that are needed now, check to be sure..
        this.checkStrings();

        //return log;
    }

    private void checkStrings() throws IOException {
        //Makes sure that none of the crucial strings is blank...
        //If an exception is thrown, then a string was blank...
//        if (simpleIn == null || simpleIn.compareTo("")==0) {
//            //We have a bad string
//            throw new IOException("SimpleIn cannot be blank.");
//        };
        if (simpleAlias == null || simpleAlias.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("SimpleAlias cannot be blank.");
        }
        
        if (xmlIn == null || xmlIn.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("xmlIn cannot be blank.");
        }
        
        if (dataOut == null || dataOut.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("dataOut cannot be blank.");
        }
        
        if (xmlSeek == null || xmlSeek.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("xmlSeek cannot be blank.");
        }
        
        if (goTerms == null || goTerms.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("goTerms cannot be blank.");
        }
       
        if (wikiDomain == null || wikiDomain.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("wikiDomain cannot be blank.");
        }
        if (wikiUsername == null || wikiUsername.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("wikiUsername cannot be blank.");
        }
       
        if (wikiPassword == null || wikiPassword.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("wikiPassword cannot be blank.");
        }
        
        if (wikiFile == null || wikiFile.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("wikiFile cannot be blank.");
        }
        
        if (botLog == null || botLog.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("botLog cannot be blank.");
        }
        
        if (wikiMainLog == null || wikiMainLog.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("WikiMainLog cannot be blank.");
        }
        
        if (wikiLogRun == null || wikiLogRun.compareTo("") == 0) {
            //We have a bad string
            throw new IOException("wikiRunLog cannot be blank.");
        }
        
    }

    //Begin Get routines:
//    public String getSimpleIn() {
//        return simpleIn;
//    }
    public String getXmlSeek() {
        return xmlSeek;
    }

    public String getSimpleAlias() {
        return simpleAlias;
    }

//    public String getSimpleOut() {
//        return simpleOut;
//    }
    public String getXmlIn() {
        return xmlIn;
    }

    public String getGoTerms() {
        return goTerms;
    }

    public String getWikiDomain() {
        return wikiDomain;
    }

    public String getWikiUsername() {
        return wikiUsername;
    }

    public String getWikiPassword() {
        return wikiPassword;
    }

    public String getWikiFile() {
        return wikiFile;
    }

    public String getBotLog() {
        return botLog;
    }

    public PbbXMLDecoder[] getXmlDecoder(String fileLocation) throws IOException {
        //Likely that File location will be from the above condfiguration file.
        File decoder = new File(fileLocation);
        LineNumberReader in;
        Vector<PbbXMLDecoder> data = new Vector<PbbXMLDecoder>();
        PbbXMLDecoder[] dataArray = new PbbXMLDecoder[1];
        if (decoder.canRead()) {
            in = new LineNumberReader(new FileReader(fileLocation));

        } else {
            throw new IOException("Cannot Read Decoder File: " + fileLocation);
        }
        String[] lineVals;
        String line = "";
        System.out.println("Parsing Decoder File...");

        line = in.readLine();
        while (line != null) {
            line = line.trim();
            if (line.compareTo("") == 0) {
                continue; //no need to mess with an empty line.

            }
            if (line.charAt(0) == '#') {
                //Skip the line
            } else {
                lineVals = line.split("\\|"); //switched to a comma deliminater
                //System.out.println("linevals length: " +lineVals.length); //DEBUG

                if (lineVals.length == 4) {
                    // good news, we have a proper line
                    PbbXMLDecoder dec = new PbbXMLDecoder();
                    dec.setAddress(lineVals[3].trim());
                    dec.setName(lineVals[0].trim());
                    dec.setReplaceCode(lineVals[1].trim(), lineVals[2].trim());
                    if ("".compareTo(lineVals[1].trim()) != 0 && "".compareTo(lineVals[2].trim()) != 0) {
                        //looks like we have character replacement data.
                        dec.setUseReplace(true);
                    } else {
                        dec.setUseReplace(false);
                    }
                    data.add(dec);
                } else {
                    //we have an error.
                    System.out.println("Error in decoder file: " + line);
                }
            }
            line = in.readLine();
        }

        dataArray = data.toArray(dataArray);
        return dataArray;
    }

    /**
     * Gets the line number.
     *
     * @throws IOException  File access error.
     */
    public int getLN() throws IOException {
        if (lnr != null) {
            return lnr.getLineNumber();
        } else {
            return 0;
        }
    }// end getLN()

    /**
     * Returns the next line from the input file.
     *
     * @return Next line from the input file. Null if no more lines.
     * @throws IOException  File access error.
     */
    public String getNextLine() throws IOException {
        if (lnr != null) {
            return lnr.readLine();
        } else {
            return null;
        }
    }// end getNextLine()

    public String getPageDir() {
        return pageDir;
    }

    public String getWikiLogRun() {
        return wikiLogRun;
    }

    public String getWikiMainLog() {
        return wikiMainLog;
    }

    public String getDataOut() {
        return dataOut;
    }
}
